package com.test.A05;

import java.io.IOException;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;

/****
 * 自定义一个后处理器 模拟@ComponentScan  
 *
 */
public class ComponentScanPostProcessor implements BeanDefinitionRegistryPostProcessor{

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		
		
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
		//得到配置文件，扫描注解的路径 ComponentScan
        try {
			ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
			if (componentScan != null) {
			    for (String p : componentScan.basePackages()) {
			        //System.out.println(p);
			        //  com.test.A05.component -> classpath*:com/test/A05/component/**/*.class
			        String path = "classpath*:" + p.replace(".", "/") + "/**/*.class";
			       // System.out.println(path);
			        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
			        Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
			        AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
			        for (Resource resource : resources) {
			            //System.out.println(resource);
			            //file [E:\workwang\lianxieclipse\ruyifast\springdemo\target\classes\com\test\A05\component\Bean4.class]
			            MetadataReader reader = factory.getMetadataReader(resource);
			             //System.out.println("类名:" + reader.getClassMetadata().getClassName());
			            AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
			           //   System.out.println("是否加了 @Component:" + annotationMetadata.hasAnnotation(Component.class.getName()));
			            // System.out.println("是否加了 @Component 派生:" + annotationMetadata.hasMetaAnnotation(Component.class.getName()));
			            if (annotationMetadata.hasAnnotation(Component.class.getName())
			                    || annotationMetadata.hasMetaAnnotation(Component.class.getName())) {//判断是否有@Component或者@Component的派生注解
			                    AbstractBeanDefinition bd = BeanDefinitionBuilder
			                            .genericBeanDefinition(reader.getClassMetadata().getClassName())
			                            .getBeanDefinition();//通过工具类得到bean定义
			                    
			                    String name = generator.generateBeanName(bd, beanFactory);//使用AnnotationBeanNameGenerator工具来生成bean别名
			                    beanFactory.registerBeanDefinition(name, bd);//把bean定义注册到bean工厂
			                }
			        }
			    }
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}
